package com.hxht.storage.server.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import com.hxht.storage.server.bean.PlanRecordDayTemplateBean;
import com.hxht.storage.server.bean.PlanRecordWeekTemplateBean;
import com.hxht.storage.server.dao.DayTemplateDao;
import com.hxht.storage.server.dao.TimePeriodDao;
import com.hxht.storage.server.dao.WeekTemplateDao;
import com.fxdigital.nvr.SchedTime;
import com.hxht.storage.server.pojo.DayTemplateInfo;
import com.hxht.storage.server.pojo.TimePeriodInfo;
import com.hxht.storage.server.pojo.WeekTemplateInfo;
import com.hxht.storage.server.service.WeekTemplateService;
import com.hxht.storage.server.util.NvrBeanTransUtil;

@Service
public class WeekTemplateServiceImpl implements WeekTemplateService{

	
	private static final Logger LOG = Logger.getLogger(WeekTemplateServiceImpl.class);
	
	@Autowired
	private WeekTemplateDao templateDao;
	
	@Autowired
	private DayTemplateDao dayTemplateDao;
	
	@Autowired
	private TimePeriodDao timePeriodDao;
	
	
	@Override
	public boolean isTemplateExist(String templateName) {

		WeekTemplateInfo template = templateDao.getTemplateByName(templateName);
		
		if (template == null){
			return false;
		} else {
			return true;
		}
		
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED, value="nvmpJpaEM")
	public boolean addWeekTemplate(PlanRecordWeekTemplateBean templateBean) {
		
		if (isTemplateExist(templateBean.getTemplateName())){
			LOG.warn("add week template fail!");
			LOG.warn("name " + templateBean.getTemplateName() + " is already exist!");
			return false;
		}
		
		WeekTemplateInfo weekTemplate = getWeekTemplateInfoFromTemplateBean(templateBean);
		
		Set<DayTemplateInfo> templateSet = getWeekTemplateFromRecordBean(templateBean);
		
		for (DayTemplateInfo dayTemplate:templateSet){
			
			dayTemplate.setWeekTemplate(weekTemplate);
			dayTemplateDao.insert(dayTemplate);
			
			for (TimePeriodInfo timePeriod:dayTemplate.getSchedTimeList()){
				timePeriod.setDayTemplate(dayTemplate);
				
				timePeriodDao.insert(timePeriod);
			}
		}
		
		LOG.info("add week template success! templateName = " + templateBean.getTemplateName());
		
		return true;
	}

	private WeekTemplateInfo getWeekTemplateInfoFromTemplateBean(
			PlanRecordWeekTemplateBean templateBean) {
		
		WeekTemplateInfo templateInfo = new WeekTemplateInfo();
		templateInfo.setIsEditable(templateBean.isEditable());
		templateInfo.setTemplateName(templateBean.getTemplateName());
		templateInfo.setUuid(templateBean.getTemplateUUID());
		
		return templateInfo;
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED, value="nvmpJpaEM")
	public boolean updateWeekTemplate(PlanRecordWeekTemplateBean templateBean) {
		
		WeekTemplateInfo template = templateDao.getByUUID(templateBean.getTemplateUUID());
		
		if (template == null){
			LOG.warn("update week template fail!");
			LOG.warn("uuid " + templateBean.getTemplateUUID() + " is not exist!");
			return false;
		}
		
		if (isTemplateExist(templateBean.getTemplateName()) && !template.getTemplateName().equals(templateBean.getTemplateName()) ){
			LOG.warn("update week template fail!");
			LOG.warn("name " + templateBean.getTemplateName() + " is already exist!");
			return false;
		}
		
		// 更改计划模板时，先将计划模板的 DayTemplateInfo 全部删除，再根据传入的信息，重新生成
		template.setIsEditable(templateBean.isEditable());
		template.setTemplateName(templateBean.getTemplateName());
		for (DayTemplateInfo dayTemplate:template.getWeekTemplate()){
			dayTemplateDao.remove(dayTemplate);
		}
		
		Set<DayTemplateInfo> templateSet = getWeekTemplateFromRecordBean(templateBean);
		
		templateDao.insert(template);
		for (DayTemplateInfo dayTemplate:templateSet){
			
			dayTemplate.setWeekTemplate(template);
			dayTemplateDao.insert(dayTemplate);
			
			
			for (TimePeriodInfo timePeriod:dayTemplate.getSchedTimeList()){
				timePeriod.setDayTemplate(dayTemplate);
				
				timePeriodDao.insert(timePeriod);
			}
		}
		
		LOG.info("update week template success! templateName = " + templateBean.getTemplateName());
		return true;
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED, value="nvmpJpaEM")
	public boolean delWeekTemplate(@RequestParam String templateName) {

		LOG.info("delet week template! templateName = " + templateName);
		
		templateDao.removeByName(templateName);
		
		return true;
	}

	@Override
	public List<PlanRecordWeekTemplateBean> getAllWeekTemplate() {
		List<WeekTemplateInfo> templateList = templateDao.findAll();
		
		List<PlanRecordWeekTemplateBean> beanList = new ArrayList<PlanRecordWeekTemplateBean>();
		
		for (WeekTemplateInfo template:templateList){
			
			PlanRecordWeekTemplateBean bean = transTemplateInfoToTemplateBean(template);
			beanList.add(bean);
		}
		
		return beanList;
	}
	
	private PlanRecordWeekTemplateBean transTemplateInfoToTemplateBean(
			WeekTemplateInfo template) {
		
		PlanRecordWeekTemplateBean weekTemplateBean = new PlanRecordWeekTemplateBean();
		
		weekTemplateBean.setTemplateUUID(template.getUuid());
		weekTemplateBean.setTemplateName(template.getTemplateName());
		
		for (DayTemplateInfo dayTemplate:template.getWeekTemplate()){
			PlanRecordDayTemplateBean dayTemplateBean = NvrBeanTransUtil.
					transDayTemplateInfoToDayTemplateBean(dayTemplate);
			
			weekTemplateBean.addTemplate(dayTemplate.getWeekIndex(), dayTemplateBean);
		}
		
		weekTemplateBean.setEditable(template.isEditable());
		
		return weekTemplateBean;
	}


	/**
	 * 将客户端传进来的计划模板转化为 存储服务器中使用的 计划模板信息 Set<DayTemplateInfo>
	 * @param recordBean
	 * @return
	 */
	private Set<DayTemplateInfo> getWeekTemplateFromRecordBean(
			PlanRecordWeekTemplateBean templateBean) {
		
		Set<DayTemplateInfo> weekTemplate = new HashSet<DayTemplateInfo>();
		
		Map<Integer, PlanRecordDayTemplateBean> weekMap = getTemplateMap(templateBean.getWeekTemplate());
		
		for (int i = 1; i< 8; i++){
			PlanRecordDayTemplateBean dayTemplateBean = weekMap.get(i);
			
			DayTemplateInfo dayTemplate;
			
			if (dayTemplateBean == null){
				dayTemplate = new DayTemplateInfo();
				dayTemplate.setWeekIndex(i);
			} else {
				dayTemplate = transDayTemplateBeanToDayTemplate(i, dayTemplateBean);
			}
			
			weekTemplate.add(dayTemplate);
		}
		
		return weekTemplate;
	}
	
	/**
	 * 计划录像星期模板的返回为Map<br/>
	 * key 为 1~7,代表星期一~星期日<br/>
	 * value 为PlanRecordDayTemplate 代表每天的计划录像时间片段模板,为null值，表示未设置。
	 * 
	 * @return
	 */
	private Map<Integer, PlanRecordDayTemplateBean> getTemplateMap(PlanRecordDayTemplateBean[] dayTemplateBeanArray) {
		Map<Integer, PlanRecordDayTemplateBean> templateMap = new HashMap<Integer, PlanRecordDayTemplateBean>();

		for (int i = 1; i <= 7; i++) {

			templateMap.put(i, dayTemplateBeanArray[i - 1]);

		}

		return templateMap;

	}

	/**
	 * 将客户端传过来的 计划录像参数中的 PlanRecordDayTemplateBean每一天的木板 转化为数据库中的DayTemplateInfo
	 * @param weekIndex
	 * @param dayTemplateBean
	 * @return
	 */
	private DayTemplateInfo transDayTemplateBeanToDayTemplate(int weekIndex,
			PlanRecordDayTemplateBean dayTemplateBean) {
		
		if (dayTemplateBean == null){
			return null;
		}
		
		DayTemplateInfo dayTemplate = new DayTemplateInfo();
		
		dayTemplate.setWeekIndex(weekIndex);
		
		if (dayTemplateBean.getPlanMode() == 1){
			dayTemplate.setIsWholeDayMode(true);
		} else {
			dayTemplate.setIsWholeDayMode(false);
		}
		
		dayTemplate.setRecordType(dayTemplateBean.getRecordtype());
		
		for (SchedTime time:dayTemplateBean.getSchedTimeList()){
			
			TimePeriodInfo timeInfo = NvrBeanTransUtil.
					transSchedTimeToTimePeriodInfo(time);
			
				dayTemplate.addSchedTime(timeInfo);
		}
		
		return dayTemplate;
		
	}

}
